package com.example.imtoken.modules.main.wallet.details

import android.annotation.SuppressLint
import android.content.Intent
import android.view.View
import androidx.annotation.IdRes
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import com.blankj.utilcode.util.*
import com.example.imtoken.R
import com.example.imtoken.core.App
import com.example.imtoken.core.base.BaseActivity
import com.example.imtoken.core.func.asAmount
import com.example.imtoken.core.utils.BusConfig
import com.example.imtoken.databinding.ActivityWalletDetailsBinding
import com.example.imtoken.entitys.http.PricesEntity
import com.example.imtoken.modules.main.wallet.details.trade.code.ReceivingCodeActivity
import com.example.imtoken.modules.main.wallet.details.trade.record.TransactionRecordFragment
import com.example.imtoken.modules.main.wallet.details.trade.transfer.TransferActivity
import com.example.imtoken.room.schema.WalletAddressSchema
import com.example.imtoken.view.MyMarkerView
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet

/**
 * 货币详情
 */
class WalletDetailsActivity :
    BaseActivity<WalletDetailsViewModel, ActivityWalletDetailsBinding>(WalletDetailsViewModel::class.java) {

    private val fragments = arrayOf(
        TransactionRecordFragment().setType(0),
        TransactionRecordFragment().setType(1),
        TransactionRecordFragment().setType(2),
        TransactionRecordFragment().setType(3)
    )

    override fun initLayoutId(): Int {
        return R.layout.activity_wallet_details
    }

    override fun init() {
        BusUtils.register(this)

        initClick()

//        initLineChart()

        initContentView()
        initListener()

//        selectTab(curIndex)
        initObserve()
    }

    private fun initFragments(coin: String?) {
        fragments.forEach {
            it.setCoin(coin)
        }
//        FragmentUtils.add(
//            supportFragmentManager,
//            fragments,
//            dataBinding.walletContent.flLayout.id,
//            0
//        )
        loadFragment(dataBinding.walletContent.flLayout.id, supportFragmentManager, fragments)
    }

    private fun loadFragment(
        @IdRes containerViewId: Int,
        supportFragmentManager: FragmentManager,
        fragments: Array<TransactionRecordFragment>
    ) {
        if (fragments.isNotEmpty()) {
            supportFragmentManager.beginTransaction().apply {
                fragments.forEach { fragment ->
                    add(containerViewId, fragment)
//                    if (fragments[showPosition] == fragment) {
//                        setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
//                    } else {
//                        hide(fragment)
//                        setMaxLifecycle(fragment, Lifecycle.State.STARTED)
//                    }
                    hide(fragment)
                    setMaxLifecycle(fragment, Lifecycle.State.STARTED)
                }
            }.commit()
            selectTab(0)
        }
    }

    private fun showHideFragment(
        supportFragmentManager: FragmentManager,
        showFragment: TransactionRecordFragment
    ) {
        supportFragmentManager.apply {
            beginTransaction().run {
                show(showFragment)
                setMaxLifecycle(showFragment, Lifecycle.State.RESUMED)

                val fs = fragments
                fs.forEach { fragment ->
                    if (fragment != showFragment) {
                        hide(fragment)
                        setMaxLifecycle(fragment, Lifecycle.State.STARTED)
                    }
                }
                commit()
            }
        }
    }

    private fun initObserve() {
        viewModel.prices.observe(this) {
            try {
                val data = it.getOrNull()
                if (data != null) {
                    initLineChart(data)
//                    setChartData(data)
                }
            } catch (e: Exception) {
                ToastUtils.showShort(e.message)
                e.printStackTrace()
            }
        }
        viewModel.getWalletDetailsLiveData().observe(this) {
            initTitle(it)
            initView(it)
        }
    }

    @BusUtils.Bus(tag = BusConfig.out_data_sticky_wallet_details_activity, sticky = true)
    fun getWalletDetails(walletAddressSchema: WalletAddressSchema) {
        viewModel.setWalletDetailsLiveData(walletAddressSchema)

        when (viewModel.getWalletDetailsLiveData().value?.walletType) {
            "eth", "usdt" -> {
                if (viewModel.getWalletDetailsLiveData().value?.fatherAddress == viewModel.getWalletDetailsLiveData().value?.address) {
                    viewModel.getPrices(walletAddressSchema.walletType)
                } else {
                    viewModel.getPrices(
                        "eth",
                        walletAddressSchema.walletType
                    )
                }
            }
            "trx", "usdj" -> {
                if (viewModel.getWalletDetailsLiveData().value?.fatherAddress == viewModel.getWalletDetailsLiveData().value?.address) {
                    viewModel.getPrices(walletAddressSchema.walletType)
                } else {
                    viewModel.getPrices(
                        "trx",
                        walletAddressSchema.walletType
                    )
                }
            }
        }
    }

    @SuppressLint("NewApi")
    private fun initListener() {
        dataBinding.svWalletDetails.setOnScrollChangeListener { _, _, scrollY, _, _ ->
            val tabViewTop = dataBinding.walletContent.llTransferTabLayout.top
            if (scrollY >= tabViewTop) {
                dataBinding.llTransferTabLayout2.visibility = View.VISIBLE
            } else {
                dataBinding.llTransferTabLayout2.visibility = View.GONE
            }
        }
    }

//    private fun initViewPager2(coin: String?) {
//        dataBinding.walletContent.vpWalletDetails.adapter =
//            WalletDetailsAdapter(coin, supportFragmentManager, lifecycle)
//        dataBinding.walletContent.vpWalletDetails.offscreenPageLimit = 4
//        dataBinding.walletContent.vpWalletDetails.isUserInputEnabled = false
//    }

    private fun initContentView() {
        dataBinding.walletContent.llTransferAll.setOnClickListener {
            selectTab(0)
        }
        dataBinding.walletContent.llTransferOut.setOnClickListener {
            selectTab(1)
        }
        dataBinding.walletContent.llTransferIn.setOnClickListener {
            selectTab(2)
        }
        dataBinding.walletContent.llTransferFail.setOnClickListener {
            selectTab(3)
        }

        dataBinding.llTransferAll2.setOnClickListener {
            selectTab(0)
        }
        dataBinding.llTransferOut2.setOnClickListener {
            selectTab(1)
        }
        dataBinding.llTransferIn2.setOnClickListener {
            selectTab(2)
        }
        dataBinding.llTransferFail2.setOnClickListener {
            selectTab(3)
        }
    }

    private fun selectTab(position: Int) {
        selectView(position)
//        FragmentUtils.showHide(fragments[position], *fragments)
        showHideFragment(supportFragmentManager, fragments[position])
    }

    private fun selectView(position: Int) {
        resetView()
        when (position) {
            0 -> {
                dataBinding.walletContent.tvTransferAll.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.walletContent.vTransferAll.visibility = View.VISIBLE

                dataBinding.tvTransferAll2.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.vTransferAll2.visibility = View.VISIBLE
            }
            1 -> {
                dataBinding.walletContent.tvTransferOut.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.walletContent.vTransferOut.visibility = View.VISIBLE

                dataBinding.tvTransferOut2.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.vTransferOut2.visibility = View.VISIBLE
            }
            2 -> {
                dataBinding.walletContent.tvTransferIn.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.walletContent.vTransferIn.visibility = View.VISIBLE

                dataBinding.tvTransferIn2.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.vTransferIn2.visibility = View.VISIBLE
            }
            3 -> {
                dataBinding.walletContent.tvTransferFail.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.walletContent.vTransferFail.visibility = View.VISIBLE

                dataBinding.tvTransferFail2.setTextColor(ColorUtils.getColor(R.color.black))
                dataBinding.vTransferFail2.visibility = View.VISIBLE
            }
        }
//        dataBinding.walletContent.vpWalletDetails.setCurrentItem(position, false)
    }

    private fun resetView() {
        dataBinding.walletContent.tvTransferAll.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.walletContent.tvTransferOut.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.walletContent.tvTransferIn.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.walletContent.tvTransferFail.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.walletContent.vTransferAll.visibility = View.INVISIBLE
        dataBinding.walletContent.vTransferOut.visibility = View.INVISIBLE
        dataBinding.walletContent.vTransferIn.visibility = View.INVISIBLE
        dataBinding.walletContent.vTransferFail.visibility = View.INVISIBLE

        dataBinding.tvTransferAll2.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.tvTransferOut2.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.tvTransferIn2.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.tvTransferFail2.setTextColor(ColorUtils.getColor(R.color.loginTextColorDef))
        dataBinding.vTransferAll2.visibility = View.INVISIBLE
        dataBinding.vTransferOut2.visibility = View.INVISIBLE
        dataBinding.vTransferIn2.visibility = View.INVISIBLE
        dataBinding.vTransferFail2.visibility = View.INVISIBLE
    }

    /**
     * 初始化图表
     */
    private fun initLineChart(pricesEntity: PricesEntity) {
        initChartStyle(pricesEntity)
        initChartLabel()
        setChartData(pricesEntity)
    }

    /**
     * 初始化图表的样式
     */
    private fun initChartStyle(pricesEntity: PricesEntity) {
//        dataBinding.lineChart.setBackgroundColor(Color.WHITE)
        //关闭描述
        dataBinding.walletContent.lineChart.description.isEnabled = false
        //设置不画背景网格
        dataBinding.walletContent.lineChart.setDrawGridBackground(false)

        // 移除x轴和y轴绘制的所有边线
        dataBinding.walletContent.lineChart.axisLeft.setDrawGridLines(false)
        dataBinding.walletContent.lineChart.axisLeft.setDrawAxisLine(false)
        dataBinding.walletContent.lineChart.xAxis.setDrawGridLines(false)
        dataBinding.walletContent.lineChart.xAxis.setDrawAxisLine(false)

        //开启所有手势触摸
        dataBinding.walletContent.lineChart.setTouchEnabled(true)
        dataBinding.walletContent.lineChart.isDragEnabled = false
        dataBinding.walletContent.lineChart.setScaleEnabled(false)
        dataBinding.walletContent.lineChart.setPinchZoom(false)

        val myMarkerView = MyMarkerView(this, R.layout.view_my_marker)
        myMarkerView.chartView = dataBinding.walletContent.lineChart
        dataBinding.walletContent.lineChart.marker = myMarkerView

        initXYAxisStyle(pricesEntity)
    }

    /**
     * 初始化图表X、Y轴的样式
     */
    private fun initXYAxisStyle(pricesEntity: PricesEntity) {
        val xAxis = dataBinding.walletContent.lineChart.xAxis
        xAxis.position = XAxis.XAxisPosition.BOTTOM
        xAxis.setLabelCount(10, true)
        xAxis.textSize = 10f
        xAxis.yOffset = 15f
        // 设置垂直的网格线
//        xAxis.enableGridDashedLine(10f, 10f, 0f)

        val yAxis = dataBinding.walletContent.lineChart.axisLeft
        // 设置水平的网格线
//        yAxis.enableGridDashedLine(10f, 10f, 0f)
        // axis range
        var min = asAmount(pricesEntity).minOrNull()?.toInt() ?: 0
        var max = (asAmount(pricesEntity).maxOrNull()?.toInt() ?: 0) + 1
        min = min.times(viewModel.getWalletDetailsLiveData().value?.amount ?: 0.0).toInt()
        max = max.times(viewModel.getWalletDetailsLiveData().value?.amount ?: 0.0).toInt() + 1
        yAxis.xOffset = 15f
        yAxis.axisMinimum = min.toFloat()
        yAxis.axisMaximum = max.toFloat()
        yAxis.setLabelCount(5, true)

        dataBinding.walletContent.lineChart.axisRight.isEnabled = false

//        val upperLimit = LimitLine(150f, "Upper Limit")
//        upperLimit.lineWidth = 4f
//        upperLimit.enableDashedLine(10f, 10f, 0f)
//        upperLimit.labelPosition = LimitLine.LimitLabelPosition.RIGHT_TOP
//        upperLimit.textSize = 10f
//
//        val lowerLimit = LimitLine(-30f, "Lower Limit")
//        lowerLimit.lineWidth = 4f
//        lowerLimit.enableDashedLine(10f, 10f, 0f)
//        lowerLimit.labelPosition = LimitLine.LimitLabelPosition.RIGHT_BOTTOM
//        lowerLimit.textSize = 10f
//
//        // draw limit lines behind data instead of on top
//        xAxis.setDrawLimitLinesBehindData(true)
//        yAxis.setDrawLimitLinesBehindData(true)
//
//        // add limit lines
//        yAxis.addLimitLine(upperLimit)
//        yAxis.addLimitLine(lowerLimit)
    }

    private fun setChartData(pricesEntity: PricesEntity) {
        val xData = arrayOfNulls<String>(pricesEntity.size)
        for (i in 0 until pricesEntity.size) {
            xData[i] = pricesEntity[i].date
        }
//        xData[0] = "07-22"
//        xData[1] = "07-24"
//        xData[2] = "07-26"
//        xData[3] = "07-28"
//        xData[4] = "07-30"
//        val formatter = object : IndexAxisValueFormatter() {
//            override fun getFormattedValue(value: Float): String? {
//                return when (value.toInt()) {
//                    0 -> xData[0]
//                    2 -> xData[2]
//                    4 -> xData[4]
//                    6 -> xData[6]
//                    8 -> xData[8]
//                    else -> "·"
//                }
//            }
//        }
        val xAxis = dataBinding.walletContent.lineChart.xAxis
//        xAxis.valueFormatter = formatter
        xAxis.valueFormatter = IndexAxisValueFormatter(xData)

        val values = run {
            val v = ArrayList<Entry>()
            for (i in 0 until pricesEntity.size) {
                val price = pricesEntity[i].amount.times(
                    viewModel.getWalletDetailsLiveData().value?.amount ?: 0.0
                ).toFloat()
                v.add(Entry(i.toFloat(), price))
            }
            v
        }

        val set1: LineDataSet
        if (dataBinding.walletContent.lineChart.data != null && dataBinding.walletContent.lineChart.data.dataSetCount > 0) {
            set1 = dataBinding.walletContent.lineChart.data.getDataSetByIndex(0) as LineDataSet
            set1.values = values
            set1.notifyDataSetChanged()
            dataBinding.walletContent.lineChart.data.notifyDataChanged()
            dataBinding.walletContent.lineChart.notifyDataSetChanged()
        } else {
            set1 = LineDataSet(values, null)
            set1.setDrawIcons(false)
            // 设置画虚线
            set1.enableDashedLine(10f, 0f, 0f)
            // 设置线的样式
            set1.color = R.color.lineChartLine
            set1.lineWidth = 1f
            // 设置点的样式
//            set1.setCircleColor(Color.BLUE)
//            set1.circleRadius = 3f
            //设置不画空心圆
            set1.setDrawCircles(false)
            set1.setDrawValues(false)

            //线条平滑,曲线
            set1.mode = LineDataSet.Mode.CUBIC_BEZIER

            // 设置数据组 标题的样式
//            set1.formLineWidth = 1f
//            set1.formLineDashEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f)
//            set1.formSize = 15f

            // text size of values
            set1.valueTextSize = 9f
            // draw selection line as dashed
//            set1.enableDashedHighlightLine(10f, 0f, 0f)

            // 设置折线图的填充区域
//            set1.setDrawFilled(true)
//            set1.setFillFormatter { _, _ ->
//                return@setFillFormatter dataBinding.lineChart.axisLeft.axisMinimum
//            }

            // 设置折线图的填充颜色
//            if (Utils.getSDKInt() >= 18) {
//                // drawables only supported on api level 18 and above
//                set1.fillColor = Color.WHITE
//            } else {
//                set1.fillColor = Color.WHITE
//            }

            val dataSets = ArrayList<ILineDataSet>()
            dataSets.add(set1)

            val data = LineData(dataSets)
            dataBinding.walletContent.lineChart.data = data
            dataBinding.walletContent.lineChart.notifyDataSetChanged()
            dataBinding.walletContent.lineChart.invalidate()
        }
    }

    /**
     * 初始化图表的 标题 样式
     */
    private fun initChartLabel() {
        val legend = dataBinding.walletContent.lineChart.legend
        legend.form = Legend.LegendForm.EMPTY
    }

    private fun initClick() {
        dataBinding.headView.ivHeadBack.setOnClickListener { this.finish() }

        ClickUtils.applyGlobalDebouncing(dataBinding.tvReceivePayment) {
            //收款二维码
            BusUtils.postSticky(
                BusConfig.out_data_sticky_receiving_code_activity,
                viewModel.getWalletDetailsLiveData().value,
            )
            val intent = Intent(this, ReceivingCodeActivity::class.java)
            when (viewModel.getWalletDetailsLiveData().value?.walletType) {
                "eth", "usdt" -> {
                    if (viewModel.getWalletDetailsLiveData().value?.fatherAddress == viewModel.getWalletDetailsLiveData().value?.address) {
                        intent.putExtra("title", "ETH")
                    } else {
                        intent.putExtra("title", "USDT")
                    }
                }
                "trx", "usdj" -> {
                    if (viewModel.getWalletDetailsLiveData().value?.fatherAddress == viewModel.getWalletDetailsLiveData().value?.address) {
                        intent.putExtra("title", "TRX")
                    } else {
                        intent.putExtra("title", "USDJ")
                    }
                }
            }
            ActivityUtils.startActivity(intent)
        }
        ClickUtils.applyGlobalDebouncing(dataBinding.tvTransfer) {
            //转账
            val intent = Intent(this, TransferActivity::class.java)
            intent.putExtra(
                "title",
                viewModel.getWalletDetailsLiveData().value?.walletType?.toUpperCase()
            )
            intent.putExtra("coin", App.createLiveData.value?.coin?.coin)
            ActivityUtils.startActivity(intent)
        }
    }

    private fun initTitle(walletAddressSchema: WalletAddressSchema) {
        dataBinding.headView.tvHeadTitles.text = walletAddressSchema.walletType?.toUpperCase()
        dataBinding.headView.vLine.visibility = View.INVISIBLE
    }

    private fun initView(walletAddressSchema: WalletAddressSchema) {
        if (walletAddressSchema.walletType == "eth" || walletAddressSchema.walletType == "usdt") {
            dataBinding.walletContent.clLayout.visibility = View.VISIBLE
        } else {
            dataBinding.walletContent.clLayout.visibility = View.GONE
        }
        dataBinding.walletContent.tvAmount.text = walletAddressSchema.amount.toString()
        dataBinding.walletContent.tvPrice.text = "≈¥ ${walletAddressSchema.price}"
//        initViewPager2(walletAddressSchema.walletType)
        initFragments(walletAddressSchema.walletType)
    }

    override fun onDestroy() {
        super.onDestroy()
        BusUtils.removeSticky(BusConfig.out_data_sticky_wallet_details_activity)
        BusUtils.unregister(this)
    }

}